#include "collisionbox.h"

void CCollisionBox::FindSATMinMax( std::vector< Vector2D > & point, Vector2D trans, Vector2D * axis, double * min, double * max )
{

	double * d = new double[point.size()];
	
	for( int j = 0; j < point.size(); j++ )
	{
		
		Vector2D np = point[j] + trans;
		
		d[j] = np.DotProduct( axis );
		
	}
	
	*min = d[0];
	*max = d[0];
	
	for( int j = 1; j < point.size(); j++ )
	{
		
		if( d[j] < *min )
			*min = d[j];
		else if( d[j] > *max )
			*max = d[j];
		
	}
		
	delete [] d;

}

bool CCollisionBox::SATQuadCollision( CCollisionBox * box2, CCollisionData & cd )
{
	
	cd.colBox1 = this;
	cd.colBox2 = box2;
	cd.bCollision = false;
	cd.minTransDist = 9999.0;
	
	Vector2D axis[5];
	
	int axis_count = 0;
	
	if( box2->m_CollisionType == CBOX_QUAD &&
		m_CollisionType == CBOX_QUAD )
	{
		
		axis_count = 2;
	
		axis[0] = m_Axis[0];
		axis[1] = m_Axis[1];
		
	} else
	{
		
		axis_count += ( m_Axis.size() + box2->m_Axis.size() );

		for( int j = 0; j < m_Axis.size(); j++ )
		{
			
			axis[j] = m_Axis[j];
			
		}
		
		for( int j = 0; j < box2->m_Axis.size(); j++ )
		{
			
			axis[j+m_Axis.size()] = box2->m_Axis[j];
			
		}
		
		
	}

	for( int j = 0; j < axis_count; j++ )
	{
		
		double minA, maxA;
		double minB, maxB;

		FindSATMinMax( m_TestPoints, m_Pos, &axis[j], &minA, &maxA );
		FindSATMinMax( box2->m_TestPoints, box2->m_Pos, &axis[j], &minB, &maxB );
		
		double d;

		if( minA < minB )
			d = minB - maxA;
		else
			d = minA - maxB;
	
		if( d > 0 )
		{
			

			return false;
		
			
		} else
		{
			
			if( fabs( d ) < cd.minTransDist )
			{
				
				cd.minTransDist = fabs( d );
				
				if( minA < minB )
					cd.minTransAxis = axis[j] * -1.0;
				else
					cd.minTransAxis = axis[j];
			
			}
				
		}
		
	}

	cd.bCollision = true;
	
	return true;
	
}

bool CCollisionBox::TestQuadCollision( CCollisionBox * box2 )
{
	
	for( int j = 0; j < 4; j++ )
	{
		
		if( ContainsPoint( box2->GetPoint( j ) ) )
			return true;
		
	}
	
	return false;
	
}

bool CCollisionBox::IsCollidingWith( CCollisionBox * box2, CCollisionData & cd )
{
	
	if( !m_bEnabled )
		return false;

	switch( m_CollisionType )
	{
		
		case CBOX_QUAD:
			return ( SATQuadCollision( box2, cd ) );
		
	}
	
	return false;

}